package com.glodon.wps.controller;

import com.glodon.wps.constant.Constants;
import com.glodon.wps.util.JSONUtil;
import com.glodon.wps.util.TokenUtils;
import com.glodon.wps.vo.ConvertParamVO;
import com.glodon.wps.vo.ConvertResultVO;
import com.glodon.wps.vo.JsonResult;
import com.glodon.wps.vo.TokenResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.Executor;

/**
 * @Title:
 * @Description:
 * @author: Haijun
 * @emial: isaiah@sohu.com
 * @date 2021/10/1815:18
 */
@RestController
@Slf4j
public class FileController {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private Executor asyncServiceExecutor;
    @Autowired
    private StringRedisTemplate redisTemplate;
    /**
     * 时间格式化
     */
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/");

    /**
     * 图片保存路径，自动从yml文件中获取数据
     *   示例： E:/images/
     */
    @Value("${file-save-path}")
    private String fileSavePath;

    @GetMapping(path = "/upload")
    public JsonResult uploadFile(MultipartFile file, HttpServletRequest request) {
        //1.后半段目录：  2020/03/15
        String directory = simpleDateFormat.format(new Date());
        /**
         *  2.文件保存目录  E:/images/2020/03/15/
         *  如果目录不存在，则创建
         */
        File dir = new File(fileSavePath + directory);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        log.info("图片上传，保存位置：" + fileSavePath + directory);
        //3.给文件重新设置一个名字
        //后缀
        String originalFilename = file.getOriginalFilename();
        String suffix = file.getOriginalFilename().substring(originalFilename.lastIndexOf("."));
        String newFileName= UUID.randomUUID().toString().replaceAll("-", "")+suffix;
        //4.创建这个新文件
        File newFile = new File(fileSavePath + directory + newFileName);
        //5.复制操作
        try {
            file.transferTo(newFile);
            //协议 :// ip地址 ：端口号 / 文件目录(/images/2020/03/15/xxx.jpg)
            String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/images/" + directory + newFileName;
            log.info("图片上传，访问URL：" + url);
            asyncServiceExecutor.execute(()->{
                sendToWps(url, originalFilename);
            });
            return JsonResult.builder().data(url).message("上传成功！").code("1").build();
        } catch (IOException e) {
            return JsonResult.builder().data(null).message("IO异常！").code("-1").build();
        }
    }

    public void sendToWps(String url, String filename){

        // 发送http请求到wps

        // 获取token
        ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
        //String token = stringStringValueOperations.get(Constants.TOKEN_KEY);
        TokenResultVO appToken = TokenUtils.getAppToken(redisTemplate);
        if (Objects.isNull(appToken)){
            appToken = doGetToken();
            Integer expireIn = appToken.getToken().getExpires_in();
            TokenUtils.setAppToken(appToken, redisTemplate, expireIn);
        }

        // 携带token调用wps转换接口
        ConvertParamVO convertParam =  new ConvertParamVO() ;
        convertParam.setDoc_filename(filename);
        convertParam.setDoc_url(url);
        convertParam.setTarget_file_format("pdf");
        Long incrementId = stringStringValueOperations.increment(Constants.INCREMENT_ID);
        convertParam.setTask_id("wps-convert-" + incrementId);
        doConvert(appToken, convertParam);


    }

    private void doConvert(TokenResultVO token, ConvertParamVO convertParam) {
        // 记录开始时间
        ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
        long currentTime = System.currentTimeMillis();
        stringStringValueOperations.set(Constants.SEND_WPS_CONVERT_TIME, currentTime + "");


        URI url = UriComponentsBuilder
                .fromHttpUrl(Constants.WPS_POST_CONVERT_URL)
                .queryParam("app_token", token.getToken().getApp_token())
                .build()
                .toUri();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        log.info("调用格式转换接口：调用前当前时间{}", currentTime);
        log.info("调用格式转换接口：请求参数{}", JSONUtil.beanToJson(convertParam));
        HttpEntity<ConvertParamVO> requestEntity = new HttpEntity<>(convertParam, headers);
        ConvertResultVO result = restTemplate.exchange(url, HttpMethod.POST, requestEntity, ConvertResultVO.class).getBody();
        log.info("调用格式转换接口：响应结果{}", JSONUtil.beanToJson(result));
        log.info("调用格式转换接口：调用前当前时间{}", currentTime);

        // 记录结束时间
    }

    private TokenResultVO doGetToken() {

        URI url = UriComponentsBuilder
                .fromHttpUrl(Constants.WPS_GET_TOKEN_URL)
                .queryParam("app_id", Constants.APPID)
                .queryParam("scope", "file_preview,file_edit,file_format_control")
                .build().toUri();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> request = new HttpEntity<>(null, headers);
        TokenResultVO result = restTemplate.exchange(url, HttpMethod.GET, request, TokenResultVO.class).getBody();
        TokenUtils.setAppToken(result, redisTemplate);
        log.info("获取Token接口响应：" + result);
        return result;
    }
}
